#include "p2p.h"

int getHost(struct hostlist *hostl[], struct sockaddr_in *hostaddr)
{
	int i;

	for(i = 0; i < 20; i++)
	{
		if((hostl[i]->on == 1) & (hostl[i]->task == 0))
		{
		
			hostaddr->sin_family = AF_INET;
			hostaddr->sin_port = htons(8081);
			hostaddr->sin_addr.s_addr = hostl[i]->host;
			break;
		}
	}
	return i;
	
}

int getTask(struct tasklist *taskl[])
{
	int i;	
	for(i = 0; i < TASK; i++)
		{
			
			if(taskl[i]->flag == 0)
			{
				break;
			}
		}
	
	return i;

}
int allTaskSum(struct tasklist *taskl[])
{
	int i;
	int sum = 0;
	for(i = 0; i < TASK; i++)
	{
		sum += taskl[i]->flag;
	}

	return sum;
}


static int count_recv = 0;

void *recvData(void *arg)
{		
		extern struct tasklist *taskl[TASK];
		int pfseek;
		extern int just[TASK];
		char p[4];
		int i, j;
		int fp, n_data;
		int flag;
		int retval;
		
		
		flag = *((int *)arg);
		pfseek = taskl[flag]->pfseek;
		sprintf(p, "%d", flag);
		fp = open(p, O_RDWR | O_CREAT | O_TRUNC, 0666);
		lseek(fp, pfseek, SEEK_SET);
		printf("open %d ok\n", flag);
		int recv_data_sockfd, data_fd;
		char data_buff[2048];
		struct sockaddr_in local, client;
		int client_len;
	
		local.sin_family = AF_INET;
		local.sin_port = htons((u_short)(8082+flag));
		local.sin_addr.s_addr = INADDR_ANY;

		recv_data_sockfd = socket(AF_INET, SOCK_STREAM, 0);
		if(recv_data_sockfd < 0)
			{
				perror("recv_data_sockfd error");
				exit(1);
			}
		j = bind(recv_data_sockfd, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
			if(j < 0)
			{
				perror("bind recv_data_sockfd error");
				exit(1);
			}
		j = listen(recv_data_sockfd, 5);
			if(j < 0){perror("listen error"); exit(1);}
		


		data_fd = accept(recv_data_sockfd, (struct sockaddr *)&client, &client_len);

		

		do{	
			n_data = recv(data_fd, data_buff, sizeof(data_buff), 0);
			just[flag] += n_data;
			printf("part %d  %d\n", flag, just[flag]);
			if(n_data > 0)
			{
							
				write(fp, data_buff, n_data);
			}
			}while(n_data > 0);

		taskl[flag]->flag = 2;
 //  	for(j=0; j < 20; j++){	if(hostl[i]->task == (flag+1)) hostl[i]->task = 0;}
		return;
}
int distriTask(char *urlBuff, int len, char *name)
{
	extern struct hostlist *hostl[20];
	extern struct tasklist *taskl[TASK];
	char url_buff[1024];
	int count_task_send;
	static int all_task = 0;
	int send_cmd_sockfd;
	int i, l, retval;
	
	

	send_cmd_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(send_cmd_sockfd < 0)
	{
		perror("socket send_cmd_sockfd error");
		exit(1);
	}

	while(all_task < 2*TASK){
		char fseek[64];
		int host_id;
		int task_id;
		struct sockaddr_in hostaddr;
	
		all_task = allTaskSum(taskl);

		host_id = getHost(hostl, &hostaddr);
		if(host_id == 20)
		{
			
			printf("no host can be use\n");
			sleep(10);
			continue;
		}
		task_id = getTask(taskl);
		if(task_id == TASK)//no task == 0
		{
			
			printf("all task start\n");
			sleep(10);
			continue;
		}
		printf("send cmd to host\n");
		i = sendto(send_cmd_sockfd, urlBuff, len, 0, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
		if(i < 0)
		{
			perror("sendto error");
			exit(1);
		}
/*
段错误
		memcpy(fseek, taskl[task_id]->task, sizeof(int));        //task
		memcpy(fseek + 4, taskl[task_id]->pfseek, sizeof(int));  //pfseek
		memset(fseek + 8, '\0', 1);
*/
		bzero(fseek, 64);

		sprintf(fseek, "%d", hostl[host_id]->hfseek);
		i = strlen(fseek);
		sprintf(fseek + i, "%d", taskl[task_id]->task);
		i = strlen(fseek);
		sprintf(fseek + i, "%d", taskl[task_id]->pfseek);
	
		i = sendto(send_cmd_sockfd, fseek, strlen(fseek), 0, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
		//=================================================
		taskl[task_id]->flag = 1;
		taskl[task_id]->host = hostl[host_id]->host;
		hostl[host_id]->task = task_id + 1;
		hostl[host_id]->hfseek = 1;   //客户端是否下载完毕

		//================================================

		count_task_send++;

	}//while
	return 0;
	
}
